package com.example.ecommercemarketing.config;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 自定义线程工厂（用于命名和监控）
 *
 * <p>实现ThreadFactory接口，用于创建具有统一命名格式和统一配置的线程</p>
 * <p>主要功能：</p>
 * <ul>
 *   <li>为线程生成有意义的名称，便于监控和问题排查</li>
 *   <li>设置线程的默认属性（非守护线程、正常优先级）</li>
 *   <li>统一处理线程未捕获异常</li>
 * </ul>
 */
@Slf4j
public class NamedThreadFactory implements ThreadFactory {

    /**
     * 线程计数器，用于生成线程编号
     * <p>使用AtomicInteger保证线程安全</p>
     */
    private final AtomicInteger threadNumber = new AtomicInteger(1);

    /**
     * 线程名前缀
     * <p>格式为："marketing-{poolName}-thread-"</p>
     */
    private final String namePrefix;

    /**
     * 构造函数
     * @param poolName 线程池名称，将作为生成线程名前缀的一部分
     */
    public NamedThreadFactory(String poolName) {
        // 构造线程名前缀，格式示例：marketing-poolName-thread-
        this.namePrefix = "marketing-" + poolName + "-thread-";
    }

    /**
     * 创建新线程
     * @param r 要在线程中执行的任务
     * @return 配置好的Thread实例
     */
    @Override
    public Thread newThread(Runnable r) {
        // 创建线程，名称格式为前缀+自增编号，如：marketing-poolName-thread-1
        Thread t = new Thread(r, namePrefix + threadNumber.getAndIncrement());

        // 设置为非守护线程（默认），这样JVM不会因为只有守护线程而退出
        t.setDaemon(false);

        // 设置线程优先级为普通优先级（默认值）
        t.setPriority(Thread.NORM_PRIORITY);

        // 设置未捕获异常处理器，记录线程中未捕获的异常
        t.setUncaughtExceptionHandler((thread, ex) -> {
            log.error("Uncaught exception in thread: {}", thread.getName(), ex);
        });

        return t;
    }
}